package personal

import (
	"context"
	"edu-common/tools"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
	asset2 "grpc-common/api/user/asset"
	"grpc-common/api/user/personal"
	"strconv"
	"user/internal/dao"
	"user/internal/logic/asset"
	"user/internal/model/entity"
)

// Asset的业务逻辑层
type PersonalLogic struct {
}

func NewPersonalLogic() *PersonalLogic {
	return &PersonalLogic{}
}

func (*PersonalLogic) GetUserList(ctx context.Context, req *personal.PageInfo) (res *personal.UserListResponse, err error) {
	var list = make([]*personal.UserInfoResponse, 0)
	md := dao.User.Ctx(ctx)
	if req.Name != "" { //模糊匹配nickname
		md = md.WhereLike(dao.User.Columns().Nickname, "%"+req.Name+"%")
	}
	if req.Mobile != "" { //模糊匹配nickname
		md = md.WhereLike(dao.User.Columns().Mobile, "%"+req.Mobile+"%")
	}
	if req.StartCreate != "" { //起始注册时间
		md = md.WhereGTE(dao.User.Columns().CreatedAt, req.StartCreate)
	}
	if req.EndCreate != "" { //终止注册时间
		md = md.WhereLTE(dao.User.Columns().CreatedAt, req.EndCreate)
	}
	//查询总数量
	count, err := md.Count()

	limit := (req.Pn - 1) * req.PSize
	err = md.Limit(int(limit), int(req.PSize)).Scan(&list)
	return &personal.UserListResponse{
		Total: int32(count),
		Data:  list,
	}, err
	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func (*PersonalLogic) GetUserByMobile(ctx context.Context, req *personal.MobileRequest) (res *personal.UserInfoResponse, err error) {
	var user *entity.User
	err = dao.User.Ctx(ctx).Where("mobile", req.Mobile).Scan(&user)
	if err == nil {
		return &personal.UserInfoResponse{
			Id:       int32(user.Id),
			Password: user.Password,
			Mobile:   user.Mobile,
			Nickname: user.Mobile,
			Birthday: user.Birthday.Format("Y-m-d H:i:s"),
			Gender:   "1",
			Role:     int32(user.Role),
			Salt:     user.Salt,
		}, err
	}
	return nil, nil
	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func (*PersonalLogic) GetUserById(ctx context.Context, req *personal.IdRequest) (res *personal.UserInfoResponse, err error) {
	var user *entity.User
	err = dao.User.Ctx(ctx).Where("id", req.Id).Scan(&user)
	if err == nil {
		return &personal.UserInfoResponse{
			Id:       int32(user.Id),
			Password: user.Password,
			Mobile:   user.Mobile,
			Nickname: user.Mobile,
			Birthday: user.Birthday.Format("Y-m-d H:i:s"),
			Gender:   "1",
			Role:     int32(user.Role),
			Salt:     user.Salt,
		}, err
	}
	return nil, nil
	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func (*PersonalLogic) CreateUser(ctx context.Context, req *personal.CreateUserInfo) (res *personal.UserInfoResponse, err error) {
	cha := make(chan struct{}, 0)
	finish := make(chan struct{}, 0)
	//wg := sync.WaitGroup{}
	//wg.Add(1)
	salt, pwd := tools.Encode(req.Password, nil)
	now := gtime.Now()
	data := g.Map{
		"nickname": req.Nickname,
		"password": pwd,
		"salt":     salt,
		"mobile":   req.Mobile,
		"birthday": now,
		"role":     0,
	}

	result, err := dao.User.Ctx(ctx).InsertAndGetId(data)
	if err != nil {
		return &personal.UserInfoResponse{}, err
	}
	cha <- struct{}{}

	go func() {
		<-cha
		g.Log().Infof(ctx, "准备创建钱包:%d", result)
		//创建钱包
		assetlogic := asset.NewAssetLogic()
		wallet, err := assetlogic.InsertWallet(ctx, &asset2.InsertWalletReq{
			CoinId: 1,
			UserId: result,
		})
		g.Log().Infof(ctx, "InsertWallet res:%+v,err:%v", wallet, err)
		finish <- struct{}{}
	}()

	//go func() {
	//	defer wg.Done()
	//	//<-cha
	//	g.Log().Infof(ctx, "准备创建钱包:%d", result)
	//	//创建钱包
	//	assetlogic := asset.NewAssetLogic()
	//	wallet, err := assetlogic.InsertWallet(ctx, &asset2.InsertWalletReq{
	//		CoinId: 1,
	//		UserId: result,
	//	})
	//	g.Log().Infof(ctx, "InsertWallet res:%+v,err:%v", wallet, err)
	//}()
	//wg.Wait()

	<-finish
	close(cha)
	close(finish)
	return &personal.UserInfoResponse{
		Id:       int32(result),
		Password: pwd,
		Mobile:   req.Mobile,
		Nickname: req.Nickname,
		Birthday: now.Format("Y-m-d H:i:s"),
		Gender:   "",
		Role:     0,
	}, err

	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func (*PersonalLogic) UpdateUser(ctx context.Context, req *personal.UpdateUserInfo) (res *personal.UpdateUserRes, err error) {
	g2 := g.Map{}
	if req.Nickname != "" {
		g2["nickname"] = req.Nickname
	}
	if req.Birthday != "" {
		g2["birthday"] = req.Birthday
	}
	if req.Gender != "" {
		g2["gender"], _ = strconv.Atoi(req.Gender)
	}
	_, err = dao.User.Ctx(ctx).Where("id", req.Id).Update(g2)
	var u *entity.User
	err = dao.User.Ctx(ctx).Where("id", req.Id).Scan(&u)
	return &personal.UpdateUserRes{
		Id:       req.Id,
		Nickname: u.Nickname,
		Gender:   strconv.Itoa(u.Gender),
		Birthday: u.Birthday.Format("Y-m-d H:i:s"),
	}, err
	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

func (*PersonalLogic) CheckPassWord(ctx context.Context, req *personal.PasswordCheckInfo) (res *personal.CheckResponse, err error) {
	verify := tools.Verify(req.Password, req.Salt, req.EncryptedPassword, nil)
	return &personal.CheckResponse{
		Success: verify,
	}, nil
	//return nil, gerror.NewCode(gcode.CodeNotImplemented)
}
